/*
     * ESP32-S3 整合WiFi、TCP和摄像头功能
     * 功能：连接WiFi成功后连接TCP服务器，TCP连接成功后启动摄像头，
     *       并将捕获的图像通过TCP发送到服务器
     */
#include "WiFiManager.h"
#include "TcpClient.h"
#include "cameraManager.h"
#include "DistanceSensorManager.h"
#include "AudioPlayer.h"

// 摄像头下电引脚定义
#define CAMERA_PWDN -1

// 距离传感器引脚定义
#define TRIGGER_PIN 21     // 接收波引脚
#define ECHO_PIN 47        // 发送波引脚
#define MAX_DISTANCE 1200  // 最大测量距离（厘米）

// RGB亮度定义
#define RGB_BRIGHTNESS 128

// WiFi配置
const char* WIFI_SSID = "TP-LINK_R32S";
const char* WIFI_PASSWORD = "RJS@147258369";
// const char* WIFI_SSID = "MERCURY_AAFB";
// const char* WIFI_PASSWORD = "#gaojinggang*";
// const char* WIFI_SSID = "iKuai-datree";
// const char* WIFI_PASSWORD = "woaigaojinyan";
// TCP服务器配置
const char* TCP_SERVER_HOST = "10.10.18.50";
// const char* TCP_SERVER_HOST = "192.168.0.15";
const uint16_t TCP_SERVER_PORT = 8400;

// LED引脚定义
// const int LED_PIN = 2;

// 创建各模块实例
WiFiManager wifiManager(WIFI_SSID, WIFI_PASSWORD);
TcpClient tcpClient(TCP_SERVER_HOST, TCP_SERVER_PORT);
CameraManager cameraManager;
DistanceSensorManager distanceSensor(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
AudioPlayer audioPlayer;

// 在代码开头定义消息类型枚举
enum TcpMessageType {
  STR_MESSAGE = 0x0001,       // 连接状态消息
  IMG_MESSAGE = 0x0002,       // 响应消息
  DISTANCE_MESSAGE = 0x0003,  // 距离传感器消息
  CONTROL_COMMAND = 0x0004    // 控制指令消息
};

// 系统状态变量
bool isSystemReady = false;

unsigned long lastPlayTime = 0;    // 上次播放时间
unsigned long playInterval = 100;  // 播放间隔


// WiFi连接状态变化处理
void onWiFiStatusChanged(bool connected) {
  // digitalWrite(LED_PIN, connected ? LOW : HIGH);
  if (connected) {
    Serial.println("WiFi已连接，准备连接TCP服务器...");
    // WiFi连接成功后，启动TCP客户端
    tcpClient.begin();
  } else {
    Serial.println("WiFi已断开，正在重连...");
#ifdef RGB_BUILTIN
    digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED off
    delay(1000);
#endif
    tcpClient.disconnect();

    isSystemReady = false;
  }
}

// TCP连接状态变化处理
void onTcpStatusChanged(bool connected) {
  if (connected) {
    Serial.println("TCP已连接，系统准备就绪。");
    isSystemReady = true;
    // 连接成功后发送问候消息
    tcpClient.send(STR_MESSAGE, "esp32s3-C6A2BC-已连接到服务器");
#ifdef RGB_BUILTIN
    digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off
#endif
    //     // 初始化摄像头
    //     CameraStatus status = cameraManager.getStatus();
    //     if (status != CAMERA_READY) {
    //       if (!cameraManager.init()) {
    //         Serial.println("摄像头初始化失败");
    //       }
    //     }
    // #ifdef RGB_BUILTIN
    //     Serial.println("粉色灯量，摄像头初始化成功");
    //     neopixelWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, RGB_BRIGHTNESS);
    // #endif
    //     // 这里是开始读取摄像头帧
    //     cameraManager.startCapture(onFrameCallback, 40);  // 25fps 表示每秒25帧，每帧间隔 1000ms/25 = 40ms
  } else {
    Serial.println("TCP已断开，稍后重连");
#ifdef RGB_BUILTIN
    digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED off

#endif
    // 停止摄像头帧捕获,销毁摄像头实例，并释放esp_camera_deinit
    cameraManager.destroy();
    isSystemReady = false;
  }
}


// 收到TCP消息处理
void onTcpMessageReceived(const String& data, uint16_t msg_type) {
  Serial.print("Server: ");
  Serial.print(" MessageType:" + String(msg_type) + " ");
  Serial.println(data);
  if (msg_type == 6) {
    Serial.println("收到关闭摄像头消息，给摄像头下电");
    digitalWrite(CAMERA_PWDN, HIGH);

    Serial.println("粉色关闭，摄像头关闭");
    digitalWrite(RGB_BUILTIN, LOW);

    // 停止摄像头帧捕获并释放资源
    cameraManager.destroy();
  }




  // 普通消息回复
  //   String response = "已收到: " + data + "\n";
  //   tcpClient.send(STR_MESSAGE,response.c_str());
}
// 摄像头状态变化回调
void onCameraStatusChanged(CameraStatus status) {
  switch (status) {
    case CAMERA_READY:
      Serial.println("摄像头已准备就绪");
      break;
    case CAMERA_RUNNING:
      Serial.println("摄像头开始捕获图像");
      break;
    case CAMERA_ERROR:
      Serial.println("摄像头错误");
      break;
    default:
      break;
  }
}



// 收到图片帧回调
void onFrameCallback(CameraFrame& frame) {
  Serial.printf("收到图片帧，大小: %d 字节\n", frame.size);
  // 当系统就绪（WiFi和TCP都已连接）时，可以通过TCP发送图像
  if (isSystemReady && frame.data && frame.size > 0) {
    tcpClient.send(IMG_MESSAGE, frame.data, frame.size);
  }
}

// 距离变化回调函数
void onDistanceChanged(double distance) {
  unsigned long currentTime = millis();
  // Serial.print("检测到距离变化: ");
  // Serial.print(distance);
  // Serial.println(" cm");
  // 当系统就绪时，可以通过TCP发送距离数据
  if (distance > 0) {
    // 根据距离设置不同的声音播放频率
    if (distance <= 10) {
      // 10cm以内：快速播放（模式3，间隔0.1秒）
      audioPlayer.setPlayMode(3);
      Serial.println("距离<=10cm，设置为模式3");
    } else if (distance > 10 && distance <= 30) {
      // 10-30cm：中速播放（模式2，间隔0.3秒）
      audioPlayer.setPlayMode(2);
      Serial.println("10cm<距离<=30cm，设置为模式2");
    } else if (distance > 30 && distance <= 50) {
      // 30-50cm：慢速播放（模式1，间隔0.5秒）
      audioPlayer.setPlayMode(1);
      Serial.println("30cm<距离<=50cm，设置为模式1");
    } else {
      // 大于50cm：停止播放
      audioPlayer.setPlayMode(0);
      Serial.println("距离>50cm，停止播放");
    }
#ifdef RGB_BUILTIN
    // 根据距离设置不同颜色，以匹配不同的声音频率
    if (distance <= 10) {
      // 10cm以内：快速播放，红色（最高频率）
      neopixelWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
    } else if (distance > 10 && distance <= 30) {
      // 10-30cm：中速播放，橙色（中等频率）
      neopixelWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, RGB_BRIGHTNESS);
    } else if (distance > 30 && distance <= 50) {
      // 30-50cm：慢速播放，黄色（较低频率）
      neopixelWrite(RGB_BUILTIN, RGB_BRIGHTNESS, RGB_BRIGHTNESS, 0);
    } else {
      // 大于50cm：停止播放，绿色（无频率）
      neopixelWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);
    }
    // 保持灯亮100ms
    if (currentTime - lastPlayTime >= playInterval) {
      lastPlayTime = currentTime;
    }
#endif
    // 直接发送距离数据
    // tcpClient.send(DISTANCE_MESSAGE, String(distance).c_str());
  } else {
    // 无效距离时停止播放
    audioPlayer.setPlayMode(0);
  }
}

void setup() {
  // 初始化串口
  Serial.begin(115200);
  while (!Serial) {
    delay(10);
  }
  Serial.println("系统启动中...");
  pinMode(CAMERA_PWDN, OUTPUT);
#ifdef RGB_BUILTIN
  Serial.println("白色灯打开开始连接wifi...");
  digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED off
  delay(1000);
#endif
  // 设置回调函数
  wifiManager.setOnConnectionStatusChanged(onWiFiStatusChanged);
  tcpClient.setOnConnectionStatusChanged(onTcpStatusChanged);
  tcpClient.setOnMessageReceived(onTcpMessageReceived);
  cameraManager.setStatusCallback(onCameraStatusChanged);
  distanceSensor.setOnDistanceChanged(onDistanceChanged);
  // 启动WiFi
  wifiManager.begin();
  // 初始化距离传感器
  distanceSensor.begin();
  // 初始化音频播放器
  audioPlayer.begin();
  // 确保音量足够大（0.5是适中值，范围0.0-1.0）
  audioPlayer.setVolume(0.2);
}

void loop() {
  // 运行WiFi管理器
  wifiManager.loop();
  // 如果WiFi已连接，运行TCP客户端
  if (wifiManager.isConnected()) {
    tcpClient.loop();
  }
  // 运行距离传感器管理器
  distanceSensor.loop();
  // 运行摄像头管理器
  cameraManager.loop();
  // 运行音频播放器
  audioPlayer.loop();
}
